// 异步 promise

const PENDING = 'PENDING'
const FULFILLED = "FULFILLED"
const REJECTED = "REJECTED"

class Promise {
  constructor(executor) {
    this.status = PENDING;
    // 存放成功状态的值，默认为 undefined
    this.value = undefined;
    // 存放失败状态的值，默认为 undefined
    this.reason = undefined;
    //存放成功的回调
    this.onResolvedCallbacks = []
    // 存放失败的回调
    this.onRejectedCallbacks = []

    let resolve = (value) => {
      if(this.status = PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 依次将对应的函数执行
        console.log(this.onResolvedCallbacks, '数组')
        this.onResolvedCallbacks.forEach(fn => fn())
      }
    }

    // 调用此方法就是失败
    let reject = (reason) => {
      if(this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 依次将对应的函数执行
        this.onRejectedCallbacks.forEach(fn => fn())
      }
    }

    try {
      // 立即执行，将 resolve 和 reject 函数传给使用者
      executor(resolve)
    } catch (error) {
      // 发生异常时执行失败逻辑
      executor(reject)
    }
  }

  // 包含一个 then 方法，并接收两个参数 onFulfilled、onRejected
  then(onFulfilled, onRejected) {
    if(this.status === FULFILLED) {
      onFulfilled(this.value)
    }

    if(this.status === REJECTED) {
      onRejected(this.reason)
    }

    // 解决调用异步问题
    if(this.status == PENDING) {
      // 如果promise的状态是 pending，需要将 onFulfilled 和 onRejected 函数存放起来，等待状态确定后，再依次将对应的函数执行
      // 面向切片编程 可以加上自己的逻辑
      this.onResolvedCallbacks.push(()=>{
        // TODO ... 自己的逻辑
        onFulfilled(this.value)
      })
    
      this.onRejectedCallbacks.push(()=>{
        onRejected(this.reason)
      })
    }
  }
}


let promise = new Promise((resolve, reject) => {
  setTimeout(()=>{
    resolve('成功')
  }, 1000)
})

.then((data) => {
    console.log('success', data)
  },
  (err) => {
    console.log('faild', err)
  }
)



// 熟悉设计模式的同学，应该意识到了这其实是一个发布订阅模式，这种收集依赖 -> 触发通知 -> 取出依赖执行的方式，被广泛运用于发布订阅模式的实现。